﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Media;


namespace KELT.Controls.Timeline.TimelineChart
{
    public class VerticalScrollSynchronizer : DependencyObject
    {

        public static readonly DependencyProperty VScrollGroupProperty =
            DependencyProperty.RegisterAttached(
            "VScrollGroup",
            typeof(string),
            typeof(VerticalScrollSynchronizer),
            new PropertyMetadata(new PropertyChangedCallback(
                OnVScrollGroupChanged)));



        public static void SetVScrollGroup(DependencyObject obj, string VScrollGroup)
        {
            obj.SetValue(VScrollGroupProperty, VScrollGroup);
        }

        public static string GetVScrollGroup(DependencyObject obj)
        {
            return (string)obj.GetValue(VScrollGroupProperty);
        }

        private static Dictionary<ScrollViewer, string> scrollViewers =
            new Dictionary<ScrollViewer, string>();

        private static Dictionary<string, double> verticalScrollOffsets =
            new Dictionary<string, double>();

        private static void OnVScrollGroupChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var scrollViewer = d as ScrollViewer;
            if (scrollViewer != null)
            {
                if (!string.IsNullOrEmpty((string)e.OldValue))
                {
                    if (scrollViewers.ContainsKey(scrollViewer))
                    {
                        scrollViewer.ScrollChanged -= new ScrollChangedEventHandler(ScrollViewer_ScrollChanged);

                        scrollViewers.Remove(scrollViewer);
                    }
                }

                if (!string.IsNullOrEmpty((string)e.NewValue))
                {
                    if (verticalScrollOffsets.Keys.Contains((string)e.NewValue))
                    {
                        scrollViewer.ScrollToVerticalOffset(verticalScrollOffsets[(string)e.NewValue]);
                    }
                    else
                    {
                        verticalScrollOffsets.Add((string)e.NewValue, scrollViewer.VerticalOffset);
                    }

                    scrollViewers.Add(scrollViewer, (string)e.NewValue);

                    scrollViewer.ScrollChanged += new ScrollChangedEventHandler(ScrollViewer_ScrollChanged);
                }
            }
        }

        private static void ScrollViewer_ScrollChanged(object sender, ScrollChangedEventArgs e)
        {
            if (e.VerticalChange != 0)
            {
                var changedScrollViewer = sender as ScrollViewer;
                Scroll(changedScrollViewer);
            }
        }

        private static void Scroll(ScrollViewer changedScrollViewer)
        {
            var group = scrollViewers[changedScrollViewer];
            verticalScrollOffsets[group] = changedScrollViewer.VerticalOffset;

            foreach (var scrollViewer in scrollViewers.Where((s) => s.Value == group && s.Key != changedScrollViewer))
            {
                if (scrollViewer.Key.VerticalOffset != changedScrollViewer.VerticalOffset)
                {
                    scrollViewer.Key.ScrollToVerticalOffset(changedScrollViewer.VerticalOffset);
                }
            }
        }
    }
}
